#pragma once
#include "base_funcs.h"

extern double alpha;
extern double p;
extern double b;
extern double c_e;
extern double c_m;
extern double h_e;
extern double h_m;
extern double theta;
extern gsl_vector* K_t;
extern gsl_vector* p_K_t;
extern gsl_vector* D_t;
extern gsl_vector* p_D_t;
extern int max_epoch; // T - 1

extern cache psi_1t_cache;
extern cache psi_2t_cache;
extern cache psi_3t_cache;
extern bool use_cache;

void init_variables(int T, bool enable_cache);
cache_data init_psi_1t_cache(double v_0, double v_1, double v_2, double v_3);
cache_data init_psi_2t_cache(double v_0, double v_1, double v_2, double v_3);
cache_data init_psi_3t_cache(double v_0, double v_1, double v_2, double v_3);
void copy_cache_data(cache_data* source, cache_data* target);
void init_model(double v_0, double v_1, double v_2, double v_3);
double init_calc(double v_0, double v_1, double v_2, double v_3);
void destroy_variables();

double psi_1t(double v_1, double v_2, double v_3, int e, int z, int epoch);
double psi_2t(double v_2, double v_3, int y, int z, int epoch);
double psi_3t(double v_3, int y, int z, int epoch);
double phi_1t(double v_0, double v_1, double v_2, double v_3, double K_t_i, int epoch);
double phi_2t(double v_0, double v_1, double v_2, double v_3, double K_t_i, int epoch);
double phi_3t(double v_0, double v_1, double v_2, double v_3, double K_t_i, int epoch);
double f_t(double v_0, double v_1, double v_2, double v_3, int epoch);